
#include "SceneEditor.h"
#include "SceneEditorPlugin.h"

#include "SceneEditorFrame.h"
#include "SceneEditorDoc.h"
#include "SceneEditorView.h"


SceneEditorPlugin::SceneEditorPlugin()
    : mPluginID(0)
    , mIcon(0)
    , mTreeItemID(0)
    , mSceneRoot(0)
    , mImageRoot(0)
{
    Q_INIT_RESOURCE(SceneEditor);

    QUuid uuid = QUuid::createUuid();
    QString strUuid = uuid.toString();
    mPluginID = qHash(uuid);
}

SceneEditorPlugin::~SceneEditorPlugin()
{
    delete mIcon;
    mIcon = 0;

    if (mSceneRoot != 0)
    {
        QTreeWidgetItem *parent = mSceneRoot->parent();

        if (parent != 0)
        {
            parent->removeChild(mSceneRoot);

            delete mSceneRoot;
        }
    }

    WindowMapItr itr = mWindows.begin();
    while (itr != mWindows.end())
    {
        delete itr.value();
        ++itr;
    }

    mWindows.clear();
}

QString SceneEditorPlugin::name() const
{
    return QString("Scene");
}

uint SceneEditorPlugin::pluginID() const
{
    return mPluginID;
}

bool SceneEditorPlugin::onCreateProject(const QString &projPath)
{
    QDir dir(projPath);

    QString scenePath = projPath + fileFolder();
    dir.mkpath(scenePath);

    QString imagePath = scenePath + "/Image";
    dir.mkpath(imagePath);

    return true;
}

bool SceneEditorPlugin::onOpenProject(const QString &projPath, QTreeWidgetItem *parent)
{
    mProjPath = projPath;
    populate(parent);

    return true;
}

bool SceneEditorPlugin::onCloseProject()
{
    return true;
}

int SceneEditorPlugin::onCreateFile(const QString &name)
{
    int userType = ITEM_UNKNOWN;
    SceneEditorDoc doc(this);
    if (doc.create(name))
    {
        userType = ITEM_SCENE;

        if (mSceneRoot != 0)
        {
            QFileInfo info(name);
            const QString &title = info.baseName();
            const QString &ext = info.suffix();
            QTreeWidgetItem *item = createTreeItem(title, ext, mSceneRoot);
            if (item != 0)
            {
                item->setData(0, Qt::UserRole, mPluginID);
            }
        }
    }

    return userType;
}

EditorWindow *SceneEditorPlugin::onOpenFile(const QString &fileName, QWidget *parent, int userType, bool &exists)
{
    EditorWindow *window = 0;

    if (userType == ITEM_SCENE)
    {
        QFileInfo info(fileName);
        const QString &title = info.baseName();
        WindowMapItr itr = mWindows.find(title);
        if (itr == mWindows.end())
        {
            exists = false;
            window = new SceneEditorFrame(mPluginID, fileName, parent);
            mWindows.insert(title, window);

            connect(window, SIGNAL(closeEditor(EditorWindow *)), this, SLOT(onCloseEditor(EditorWindow *)));
        }
        else
        {
            exists = true;
            window = itr.value();
        }
    }

    return window;
}

bool SceneEditorPlugin::onCloseFile()
{
    return true;
}

void SceneEditorPlugin::onRefresh()
{

}

QIcon *SceneEditorPlugin::icon()
{
    if (mIcon != 0)
        return mIcon;

    return (mIcon = new QIcon(":/Icons/scene.svg"));
}

QString SceneEditorPlugin::fileExtension() const
{
    return QString("scene");
}

QString SceneEditorPlugin::fileFolder() const
{
    return QString("Scene");
}

bool SceneEditorPlugin::onExport(Packer *packer)
{
    return true;
}

bool SceneEditorPlugin::onImport(Unpacker *unpacker)
{
    return true;
}

void SceneEditorPlugin::populate(QTreeWidgetItem *parent)
{
    QString scenePath = mProjPath + "/" + fileFolder();
    QString imagePath = scenePath + "/Image";

    QDir dir(scenePath);
    if (dir.exists())
    {
        QString ext = fileExtension();
        QTreeWidgetItem *item = createTreeItem(fileFolder(), ext, parent);
        if (item != 0)
        {
            mSceneRoot = item;
            populate(item, scenePath);
            if (mImageRoot != 0)
            {
                populate(mImageRoot, imagePath);
            }
        }
    }
}

void SceneEditorPlugin::populate(QTreeWidgetItem *parent, const QString &location, const QString &filter /* = "" */)
{
    QDir dir(location);
    QStringList filters;
    QDir::Filters flag;
    if (!filter.isEmpty())
    {
        filters<<filter;
        flag = QDir::Dirs|QDir::Files|QDir::NoSymLinks|QDir::NoDotAndDotDot;
    }
    else
    {
        flag = QDir::NoFilter;
    }

    QFileInfoList list = dir.entryInfoList(filters, flag, QDir::Name);
    QFileInfoList::const_iterator itr = list.constBegin();

    while (itr != list.constEnd())
    {
        const QFileInfo &info = *itr;
        const QString &title = info.baseName();
        const QString &ext = info.suffix();

        QTreeWidgetItem *item = createTreeItem(title, ext, parent);

        if (info.isDir() && item != 0)
        {
            if (title == "Image")
            {
                mImageRoot = item;
            }
            item->setData(0, Qt::UserRole, mPluginID);
        }
        else if (item != 0)
        {
            item->setData(0, Qt::UserRole, mPluginID);
            mTreeItemID++;
        }

        ++itr;
    }
}

QTreeWidgetItem *SceneEditorPlugin::createTreeItem(const QString &title, const QString &ext, QTreeWidgetItem *parent /* = 0 */)
{
    QTreeWidgetItem *item = 0;

    if (ext.isEmpty())
    {
        if (title == "Image")
        {
            item = new QTreeWidgetItem(parent, ITEM_FOLDER);
            item->setIcon(0, QIcon(":/Icons/folder.svg"));
            item->setText(0, title);
        }
    }
    else if (ext.compare("jpg", Qt::CaseInsensitive) == 0 || ext.compare("jpeg", Qt::CaseInsensitive) == 0)
    {
        item = new QTreeWidgetItem(parent, ITEM_JPG);
        item->setIcon(0, QIcon(":/Icons/icon_jpg.png"));
        item->setText(0, title);
    }
    else if (ext.compare("bmp", Qt::CaseInsensitive) == 0)
    {
        item = new QTreeWidgetItem(parent, ITEM_BMP);
        item->setIcon(0, QIcon(":/Icons/icon_bmp.png"));
        item->setText(0, title);
    }
    else if (ext.compare("png", Qt::CaseInsensitive) == 0)
    {
        item = new QTreeWidgetItem(parent, ITEM_PNG);
        item->setIcon(0, QIcon(":/Icons/icon_png.png"));
        item->setText(0, title);
    }
    else if (ext.compare("Scene", Qt::CaseInsensitive) == 0)
    {
        item = new QTreeWidgetItem(parent, ITEM_SCENE);
        item->setIcon(0, QIcon(":/Icons/scene.svg"));
        item->setText(0, title);
    }

    return item;
}

void SceneEditorPlugin::onCloseEditor(EditorWindow *editor)
{
    WindowMapItr itr = mWindows.find(editor->name());

    if (itr != mWindows.end())
    {
        mWindows.erase(itr);
    }
}
